﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FlashCards.WebApp.DataAccessLayer;
using FlashCards.Model;
using System.Data.Objects;

namespace FlashCards.WebApp.Utils
{
    public class FriendshipUtils
    {
        public static void AddInvitation(string senderName, int receiverId)
        {
            using (var context = new FlashCardsEntities())
            {
                var sender = context.Users.FirstOrDefault(x => x.Nick == senderName);

                if (sender != null)
                {
                    var friendship = new Friendship { SenderId = sender.UserId, ReceiverId = receiverId, IsConfirmed = false };

                    context.Friendships.AddObject(friendship);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Wyszukuje użytkowników których imie lub nazwisko pasuje do wzorca
        /// </summary>
        /// <param name="searchPattern">wzorzec</param>
        /// <param name="userName"> </param>
        /// <returns></returns>
        public static List<User> GetUnknownUsers(string searchPattern, string userName)
        {
            var list = new List<User>();

            using (var context = new FlashCardsEntities())
            {
                var user = context.Users.FirstOrDefault(x => x.Nick == userName);

                searchPattern = searchPattern.Trim();

                var users = context.Users
                    .Where(x => (x.Name + " " + x.Surname).ToLower().Contains(searchPattern)
                            || (x.Surname + " " + x.Name).ToLower().Contains(searchPattern)
                            || (x.Name).ToLower().Contains(searchPattern))
                    .Where(x => x.Nick != userName)
                    .ToList();

                var friendsWhereSender = context.Friendships
                    .Where(x => x.Sender.UserId == user.UserId)
                    .Select(x => x.Receiver).ToList();

                var friends = context.Friendships
                    .Where(x => x.Receiver.UserId == user.UserId)
                    .Select(x => x.Sender).ToList()
                    .Union(friendsWhereSender).ToList();
                    
                var usersToRemove = new List<User>();

                foreach (var friend in friends)
                {
                    //TODO: zaczac od tego miejsca

                    if (users.Contains(friend))
                        usersToRemove.Add(friend);
                }

                foreach (var userToRemove in usersToRemove)
                {
                    users.Remove(userToRemove);
                }

                list.AddRange(users);
            }

            return list;
        }

        public static List<User> GetUserFriends(string userName)
        {
            var friends = new List<User>();
            using(var context = new FlashCardsEntities())
            {
                var user = context.Users.FirstOrDefault(x => x.Nick == userName);

                var senderFriends = context.Friendships.Where(x => x.ReceiverId == user.UserId && x.IsConfirmed).Select(x => x.Sender) as ObjectQuery<User>;
                var receiverFriends = context.Friendships.Where(x => x.SenderId == user.UserId && x.IsConfirmed).Select(x => x.Receiver) as ObjectQuery<User>;
                
                //senderFriends = senderFriends.Include("Avatar");
                //receiverFriends = receiverFriends.Include("Avatar");

                friends.AddRange(senderFriends.ToList());
                friends.AddRange(receiverFriends.ToList());
            }
            return friends;
        }

        public static List<User> GetInvitationsReceived(string userName)
        {
            var invitations = new List<User>();
            using(var context = new FlashCardsEntities())
            {
                var user = context.Users.FirstOrDefault(x => x.Nick == userName);

                var senders = user.FriendshipsAsReceiver
                    .Where(x => x.IsConfirmed == false)
                    .Select(x => x.Sender)
                    .ToList();

                invitations.AddRange(senders);
            }
            return invitations;
        }

        public static List<User> GetInvitationsSent(string userName)
        {
            var invitations = new List<User>();
            using(var context = new FlashCardsEntities())
            {
                var user = context.Users.FirstOrDefault(x => x.Nick == userName);

                var receivers = user.FriendshipsAsSender
                    .Where(x => x.IsConfirmed == false)
                    .Select(x => x.Receiver)
                    .ToList();

                invitations.AddRange(receivers);
            }
            return invitations;
        }

        public static void ConfirmFriendship(string userName, string friendName)
        {
            using(var context = new FlashCardsEntities())
            {
                var user = context.Users.FirstOrDefault(x => x.Nick == userName);
                var friend = context.Users.FirstOrDefault(x => x.Nick == friendName);

                if(user != null && friend != null)
                {
                    var friendship = context.Friendships
                        .Where(x => x.Receiver.UserId == user.UserId)
                        .Where(x => x.Sender.UserId == friend.UserId)
                        .Where(x => x.IsConfirmed == false)
                        .FirstOrDefault();

                    if (friendship != null)
                    {
                        friendship.IsConfirmed = true;
                        context.SaveChanges();
                    }
                }
            }
        }

        public static void DeleteFriendship(string userName, string friendName)
        {
            using (var context = new FlashCardsEntities())
            {
                var user = context.Users.FirstOrDefault(x => x.Nick == userName);
                var friend = context.Users.FirstOrDefault(x => x.Nick == friendName);

                if (user != null && friend != null)
                {
                    var friendship = context.Friendships
                        .Where(x => x.SenderId == user.UserId || x.ReceiverId == user.UserId)
                        .Where(x => x.SenderId == friend.UserId || x.ReceiverId == friend.UserId)
                        .FirstOrDefault();

                    if (friendship != null)
                    {
                        context.Friendships.DeleteObject(friendship);
                        context.SaveChanges();
                    }
                }
            }
        }
    }
}